/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package src.tarea1;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author jorgeorm
 */
public class PruebaChi {
    private int numeroClases;
    private double chiCalculado, tamanoClase;
    private List <Double> arrayDatos;
    private List <Integer> arrayFreq;
    private List <Clase> arrayClases;

    public int getNumeroClases() {
        return numeroClases;
    }

    public void setNumeroClases(int numeroClases) {
        this.numeroClases = numeroClases;
    }

    public double getChiCalculado() {
        return chiCalculado;
    }

    public void setChiCalculado(double chiCalculado) {
        this.chiCalculado = chiCalculado;
    }
    
    public PruebaChi(List<Double> arrayDatos){
        this.arrayDatos= arrayDatos;
        numeroClases= (int) Math.floor(
                Math.sqrt((double)arrayDatos.size()));
        
        /*Instancio los arreglos de Clases y datos
         */
        arrayClases= new ArrayList<>(numeroClases);
        arrayFreq = new ArrayList<>(numeroClases);
        
        
        /*Seteo el array de Clases y frecuencias
         */
        tamanoClase= 1.0 /(double)numeroClases;        
//        tamanoClase=Math.round(tamanoClase*10000.0)/10000.0;
        double cotaInf=0;
        double cotaSup=tamanoClase;
        
        for(int idClase=0; idClase < numeroClases; idClase++){
            arrayClases.add(new Clase(cotaInf,cotaSup));
            arrayFreq.add(0);
            cotaInf= cotaSup;
            cotaSup= cotaSup+tamanoClase;
        }
        Clase clasesita= arrayClases.get(arrayClases.size()-1);
        clasesita.setCotaSup(1.0);
//        imprimpirClases();
        
        
        contarFrecuencias();
    }
    
    public void contarFrecuencias(){
        int idTmp=0;
        int valueTmp=0;
        for (Double dato : arrayDatos) {
            idTmp= busquedaBinariaClases(dato);
            valueTmp =  arrayFreq.get(idTmp);
            valueTmp++;
            arrayFreq.set(idTmp, valueTmp);
        }
    }
    
    public void imprimpirClases(){
        int contador=0;
        for (Clase clasesita : arrayClases) {
            System.out.println("Clase ["+contador+"]:"+clasesita);
            contador++;
        }
    }
    
    public void imprimirFrecuencias(){
        int contador=0;
        
        for (Integer frecuencia : arrayFreq) {
            System.out.println("Clase["+contador+"]: "+frecuencia);
            contador++;
        }
    }
    
    public void calcularChiCalculadoUniforme(){
        double chi=0;
        double r=0;
        double freqEsp=(1.0/(double)numeroClases)
                *(double)arrayDatos.size();
        
        for (int freqObs : arrayFreq) {
            r=Math.pow((freqEsp-(double)freqObs),2.0);
            chi+=r/freqEsp;                        
        }
        
        chiCalculado= chi;
    }
    
    public int busquedaBinariaClases(double dato){
        int mitad= (int) Math.floor((double)numeroClases/2.0);
        int idInf, idSup;
        idInf=0; idSup=numeroClases-1;
        
        Clase casesitaTmp=arrayClases.get(mitad);
        
        while(!casesitaTmp.pertenece(dato)){
//            
//            System.out.println("Resultado pertence: "+casesitaTmp.pertenece(dato));
//            System.out.println("CotaInfArray: "+idInf+", CotaSupArray: "+idSup);
//            System.out.println("dato: "+dato+",mitad: "+mitad+", cotaInfInt: "+casesitaTmp.getCotaInf()+
//                    ", cotaSupInt: "+casesitaTmp.getCotaSup());
            
            
            if(casesitaTmp.mayorQue(dato)){
                idSup=mitad;
            }else if(casesitaTmp.menorQue(dato)) {
                idInf=mitad;
            }
            
            
            if((idSup-idInf)==1){
                Clase calseSup= arrayClases.get(idSup);
                casesitaTmp= arrayClases.get(idInf);
                if(casesitaTmp.pertenece(dato)){
                    mitad= idInf;
                }
                else if(calseSup.pertenece(dato)){
                    mitad= idSup;
                    casesitaTmp= calseSup;
                }
                break;
            }else{
                mitad=(int)Math.floor((double)idInf+(double)(idSup-idInf)/2.0);
                casesitaTmp= arrayClases.get(mitad);
            }
            
        }
//        System.out.println("Resultado pertence: "+casesitaTmp.pertenece(dato));
//        System.out.println("CotaInfArray: "+idInf+", CotaSupArray: "+idSup);
//        System.out.println("dato: "+dato+",mitad: "+mitad+", cotaInfInt: "+casesitaTmp.getCotaInf()+
//                ", cotaSupInt: "+casesitaTmp.getCotaSup());
        
//        System.out.println("Sali de búsqueda binaria");
        
        return mitad;
    }

    public double getTamanoClase() {
        return tamanoClase;
    }
    
    
    
}
